﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace lbjson
{
    public class JsonReader
    {
        private string jsonText;
        private int currentIndex;
        private char currentChar;
        // 暂时使用public方便外部调试
        public List<Token> tokens;
        public JsonReader(string jsonText)
        {
            this.jsonText = jsonText;
            if (jsonText == null || jsonText.Length == 0)
            {
                //TODO 抛出异常
                return;
            }
            currentIndex = 0;
            currentChar = jsonText[currentIndex];
            tokens = new List<Token>();
        }
        public void Test()
        {
            Parse();
        }
        private bool Parse()
        {
            do
            {
                switch (currentChar)
                {
                    case '{':
                        SetToken(JsonToken.StartObject,"{");
                        break;
                    case '}':
                        SetToken(JsonToken.EndObeject,"}");
                        break;
                    case '"':
                        ParsePropertyName('/');
                        break;
                    case '=':
                        ParseValue('/');
                        break;
                    default:
                        break;
                }
            } while (MoveNext());
            
            return false;
        }

        private void ParseValue(char v)
        {
            bool isValueEnd = false;
            MoveNext();
            do
            {
                switch (currentChar)
                {
                    case '"':
                        SetToken(JsonToken.String,ParseString('/'));
                        
                        isValueEnd = true;
                        break;
                    case 't':
                    case 'f':
                        GetBoolToken();
                        isValueEnd = true;
                        break;
                        //空格跳过
                    case ' ':
                        break;
                    default:
                        break;
                }
                if (isValueEnd)
                {
                    MoveNext();
                    break;
                }
            } while (MoveNext());
        }

        private void ParsePropertyName(char v)
        {
            SetToken(JsonToken.PropertyName, ParseString(v));
        }
        /// <summary>
        /// 字符解析，" 开始  "结束
        /// </summary>
        /// <param name="quote"></param>
        private String ParseString(char quote)
        {
            bool isStringEnd = false;
            StringBuilder str = new StringBuilder();
            while (!isStringEnd && MoveNext())
            {
                switch (currentChar)
                {
                    case '"':
                        isStringEnd = true;
                        break;
                    default:
                        str.Append(currentChar);
                        break;
                }
            }

            if (!isStringEnd)
            {
                // TODO: 抛出异常
                return "Json format error";
            }
            else
            {
                // 记录下解析的string
                return str.ToString();
            }
        }

        private void SetToken(JsonToken token, string str)
        {
            tokens.Add(new Token(token, str));
        }


        #region bwm

        private bool MoveNext()
        {
            if (currentIndex+1>=jsonText.Length)
            {
                return false;
            }
            else
            {
                currentChar = jsonText[++currentIndex];
                return true;
            }
        }
        /// <summary>
        /// 获取Bool Token流
        /// </summary>
        private void GetBoolToken()
        {
            MoveNext();
            // TODO 错误退回判断
            int count = currentIndex;
            bool flag = false;

            var c = jsonText[currentIndex];
            if (c == 'r')
            {
                MoveNext();
                c = GetCurrentChar();
                if (c == 'u')
                {
                    MoveNext();
                    c = GetCurrentChar();
                    if (c == 'e')
                    {
                        SetToken(JsonToken.Boolean, "true");
                    }
                }
            }
            if (c == 'a')
            {
                MoveNext();
                c = GetCurrentChar();
                if (c == 'l')
                {
                    if (c == 'c')
                    {
                        MoveNext();
                        c = GetCurrentChar();
                        if (c == 'e')
                        {
                            SetToken(JsonToken.Boolean, "false");
                            flag = true;
                        }
                    }
                }
            }

            if (!flag)
            {
                //TODO  如何在 ParseValue 跳过Bool 类型的判断
                // 退回进入方法时候的下标 
                currentIndex = count;
            }
        }
        private char GetCurrentChar()
        {
            return jsonText[currentIndex];
        }
        #endregion
    }
}
